import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from PIL import Image, ImageTk
import os
import numpy as np
import image_channels
import image_io
import image_transform
import config
import sys
from image_utils import language_data, logging
import image_utils as utils
import subprocess


class ImageProcessor:
    def __init__(self, master):
        self.master = master
        self.current_language = language_data["current_language"]
        master.title(language_data[self.current_language]['app_title'])

        self.image = None
        self.image_path = ""
        self.rect_start_x = None
        self.rect_start_y = None
        self.rect_end_x = None
        self.rect_end_y = None
        self.is_drawing = False
        self.current_rect = None

        self.create_widgets()

    def create_widgets(self):
        menubar = tk.Menu(self.master)
        self.master.config(menu=menubar)

        file_menu = tk.Menu(menubar)
        file_menu.add_command(label=language_data[self.current_language]['open_original'], command=self.Open_as_original)
        file_menu.add_command(label=language_data[self.current_language]['open_grayscale'], command=self.Open_as_gray)
        file_menu.add_command(label=language_data[self.current_language]['merge_channels'], command=self.merge_channels)
        file_menu.add_command(label=language_data[self.current_language]['save_image'], command=self.save_image)
        file_menu.add_separator()

        language_menu = tk.Menu(file_menu)
        self.language_var = tk.StringVar(value=self.current_language)
        language_menu.add_radiobutton(label="中文", variable=self.language_var, value="zh", command=self.change_language)
        language_menu.add_radiobutton(label="English", variable=self.language_var, value="en", command=self.change_language)
        file_menu.add_cascade(label=language_data[self.current_language]['language'], menu=language_menu)

        file_menu.add_command(label=language_data[self.current_language]['exit'], command=self.master.quit)
        menubar.add_cascade(label=language_data[self.current_language]['file'], menu=file_menu)

        info_menu = tk.Menu(menubar)
        info_menu.add_command(label=language_data[self.current_language]['details'], command=self.show_image_details)
        menubar.add_cascade(label=language_data[self.current_language]['info'], menu=info_menu)

        edit_menu = tk.Menu(menubar)
        edit_menu.add_command(label=language_data[self.current_language]['crop'], command=self.crop_image)
        edit_menu.add_command(label=language_data[self.current_language]['reset'], command=self.reset_image)
        edit_menu.add_command(label=language_data[self.current_language]['brightness_adjust'], command=self.adjust_brightness)
        menubar.add_cascade(label=language_data[self.current_language]['edit'], menu=edit_menu)

        split_menu = tk.Menu(menubar)
        menubar.add_cascade(label=language_data[self.current_language]['split'], menu=split_menu)
        split_menu.add_command(label=language_data[self.current_language]['split_channels'], command=self.split_image_channels)

        threshold_menu = tk.Menu(menubar)
        menubar.add_cascade(label=language_data[self.current_language]['threshold_processing'], menu=threshold_menu)
        threshold_menu.add_command(label=language_data[self.current_language]['global_threshold_processing'], command=self.global_threshold_processing)

        edge_menu = tk.Menu(menubar)
        menubar.add_cascade(label=language_data[self.current_language]['edge'], menu=edge_menu)
        edge_menu.add_command(label=language_data[self.current_language]['moving_difference'], command=self.moving_difference)

        mask_menu = tk.Menu(menubar)
        menubar.add_cascade(label=language_data[self.current_language]['mask'], menu=mask_menu)
        mask_menu.add_command(label=language_data[self.current_language]['generate_red_mask'], command=lambda: self.generate_mask("red"))
        mask_menu.add_command(label=language_data[self.current_language]['generate_green_mask'], command=lambda: self.generate_mask("green"))
        mask_menu.add_command(label=language_data[self.current_language]['generate_blue_mask'], command=lambda: self.generate_mask("blue"))

        apply_mask_menu = tk.Menu(menubar)
        menubar.add_cascade(label=language_data[self.current_language]['apply_mask'], menu=apply_mask_menu)
        apply_mask_menu.add_command(label=language_data[self.current_language]['apply_and_mask'], command=self.apply_and_mask)
        apply_mask_menu.add_command(label=language_data[self.current_language]['apply_not_mask'], command=self.apply_not_mask)

        self.canvas = tk.Canvas(self.master, width=600, height=400)
        self.canvas.pack()

        self.canvas.bind("<Button-1>", self.on_mouse_down)
        self.canvas.bind("<B1-Motion>", self.on_mouse_move)
        self.canvas.bind("<ButtonRelease-1>", self.on_mouse_up)

    def change_language(self):
        self.current_language = self.language_var.get()
        utils.write_language_data(language_data, "current_language", self.current_language)
        logging.info(f"当前语言已切换为{self.current_language}。")
        confirm = messagebox.askyesno(language_data[self.current_language]['confirm_restart'],
                                      language_data[self.current_language]['restart_warning'])
        if confirm:
            self.master.destroy()
            subprocess.Popen([sys.executable] + sys.argv)

    def merge_channels(self):
        file_paths = filedialog.askopenfilenames()
        if not file_paths:
            return
        if len(file_paths) == 1:
            tk.messagebox.showerror(language_data[self.current_language]['error'], language_data[self.current_language]['single_file_error'])
            return
        try:
            self.image = image_channels.merge_image_channels(file_paths)
        except ValueError as e:
            tk.messagebox.showerror(language_data[self.current_language]['error'], str(e))
            return
        self.display_image()

    def split_image_channels(self):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_loaded'])
            return
        if len(self.image.shape) == 2:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['single_channel_error'])
            return
        try:
            channels = image_channels.split_image_channels(self.image)
        except ValueError as e:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], str(e))
            return
        for i, channel in enumerate(channels):
            window = tk.Toplevel(self.master)
            window.title(language_data[self.current_language]['channel_title'].format(i))
            canvas = tk.Canvas(window, width=300, height=300)
            canvas.pack()

            def save_channel(channel, index):
                save_path = filedialog.asksaveasfilename(defaultextension=config.DEFAULT_SAVE_FORMAT)
                if not save_path:
                    return
                image_io.save_image(channel, save_path)
                tk.messagebox.showinfo(language_data[self.current_language]['success'], language_data[self.current_language]['channel_saved'].format(index, save_path))

            save_button = tk.Button(window, text=language_data[self.current_language]['save_channel'], command=lambda channel=channel: save_channel(channel, i))
            save_button.pack()

            window.update()

            image = Image.fromarray(channel)
            canvas_width = canvas.winfo_width()
            canvas_height = canvas.winfo_height()
            image_width, image_height = image.size
            scale = min(canvas_width / image_width, canvas_height / image_height)
            if scale < 1:
                new_width = int(image_width * scale)
                new_height = int(image_height * scale)
                image = image.resize((new_width, new_height), Image.LANCZOS)
            else:
                new_width = int(image_width * scale)
                new_height = int(image_height * scale)
                image = image.resize((new_width, new_height), Image.BICUBIC)

            photo = ImageTk.PhotoImage(image)
            x = (canvas_width - new_width) // 2
            y = (canvas_height - new_height) // 2
            canvas.create_image(x, y, anchor=tk.NW, image=photo)
            canvas.image = photo

            title = f"Channel {i}"
            canvas.create_text(canvas_width // 2, 15, text=title, font=("Arial", 15), fill="black")

        logging.info("图像分割操作成功。")

    def show_image_details(self):
        if self.image is None:
            messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_loaded'])
            logging.info("没有载入任何图像,无法显示图像细节。")
            return
        filename = os.path.basename(self.image_path)
        total_pixels = self.image.size
        shape = self.image.shape
        channels = self.image.shape[2] if len(self.image.shape) == 3 else 1
        dtype = self.image.dtype
        details = language_data[self.current_language]['info_str'].format(filename, total_pixels, shape, channels, dtype)
        messagebox.showinfo("INFO", details)
        logging.info("已显示图像细节。")

    def on_mouse_down(self, event):
        if self.current_rect and not self.is_drawing:
            self.canvas.delete(self.current_rect)
            self.current_rect = None
        else:
            self.rect_start_x = event.x
            self.rect_start_y = event.y
            self.is_drawing = True

    def on_mouse_move(self, event):
        if self.is_drawing:
            if self.current_rect:
                self.canvas.delete(self.current_rect)
            self.current_rect = self.canvas.create_rectangle(self.rect_start_x, self.rect_start_y, event.x, event.y, outline="red")

    def on_mouse_up(self, event):
        self.rect_end_x, self.rect_end_y = event.x, event.y
        self.is_drawing = False
        self.crop_region = (min(self.rect_start_y, self.rect_end_y), max(self.rect_start_y, self.rect_end_y),
                            min(self.rect_start_x, self.rect_end_x), max(self.rect_start_x, self.rect_end_x))
        logging.info("已绘制裁剪区域。")

    def Open_as_original(self):
        logging.info("正在打开原始图像...")
        self.image_path = filedialog.askopenfilename()
        if not self.image_path:
            logging.info("没有选择任何图像文件,打开操作已取消。")
            return
        self.image = image_io.load_image(self.image_path)
        self.display_image()
        logging.info("成功打开原始图像。")

    def Open_as_gray(self):
        self.image_path = filedialog.askopenfilename()
        if not self.image_path:
            logging.info("没有选择任何图像文件,打开操作已取消。")
            return
        self.image = image_io.load_image(self.image_path, as_gray=True)
        self.display_image()
        logging.info("成功打开并转换为灰度图像。")

    def display_image(self):
        if self.image is None:
            logging.info("当前没有图像可显示。")
            return
        image = Image.fromarray(self.image)
        canvas_width = self.canvas.winfo_width()
        canvas_height = self.canvas.winfo_height()
        image_width, image_height = image.size
        scale = min(canvas_width / image_width, canvas_height / image_height)
        if scale < 1:
            new_width = int(image_width * scale)
            new_height = int(image_height * scale)
            image = image.resize((new_width, new_height), Image.LANCZOS)
        else:
            new_width = int(image_width * scale)
            new_height = int(image_height * scale)
            image = image.resize((new_width, new_height), Image.BICUBIC)
        photo = ImageTk.PhotoImage(image)
        self.canvas.delete("all")
        x = (canvas_width - new_width) // 2
        y = (canvas_height - new_height) // 2
        self.canvas.create_image(x, y, anchor=tk.NW, image=photo)
        self.canvas.image = photo
        logging.info("成功显示图像。")

    def save_image(self):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_to_be_saved'])
            logging.error("没有图像可保存,保存操作已取消。")
            return
        save_path = filedialog.asksaveasfilename(defaultextension=config.DEFAULT_SAVE_FORMAT)
        if not save_path:
            logging.info("没有选择保存路径,保存操作已取消。")
            return
        image_io.save_image(self.image, save_path)
        logging.info(f"图像已成功保存到 {save_path}。")

    def crop_image(self):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_to_be_cropped'])
            logging.error("没有图像可裁剪,裁剪操作已取消。")
            return
        if hasattr(self, 'crop_region') and self.current_rect:
            image_height, image_width = self.image.shape[:2]
            canvas_width = self.canvas.winfo_width()
            canvas_height = self.canvas.winfo_height()
            scale = min(canvas_width / image_width, canvas_height / image_height)
            offset_x = (canvas_width - image_width * scale) // 2
            offset_y = (canvas_height - image_height * scale) // 2
            real_crop_region = (
                int((self.crop_region[0] - offset_y) / scale),
                int((self.crop_region[1] - offset_y) / scale),
                int((self.crop_region[2] - offset_x) / scale),
                int((self.crop_region[3] - offset_x) / scale)
            )
            cropped_image = image_transform.crop_image(self.image, real_crop_region)
            if cropped_image is not None:
                self.image = cropped_image
                self.display_image()
                logging.info("图像裁剪成功。")
                self.canvas.delete(self.current_rect)
                self.current_rect = None
                del self.crop_region
            else:
                tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['crop_failed'])
                logging.error("裁剪操作失败。")
        else:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_crop_area'])
            logging.error("没有选择裁剪区域,裁剪操作已取消。")

    def reset_image(self):
        if not self.image_path:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_reset_image'])
            logging.error("没有图像可重置,重置操作已取消。")
            return
        self.image = image_io.load_image(self.image_path)
        self.display_image()
        logging.info("图像已重置为原始状态。")

    def adjust_brightness(self):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_to_be_adjusted'])
            logging.error("没有图像可调节亮度,亮度调节操作已取消。")
            return
        brightness_window = tk.Toplevel(self.master)
        brightness_window.title(language_data[self.current_language]['brightness_adjust'])
        brightness_scale = tk.Scale(brightness_window, from_=0, to=200, orient=tk.HORIZONTAL,
                                    label=language_data[self.current_language]['brightness_percentage'],
                                    command=lambda value: self.update_brightness(float(value) / 100))
        brightness_scale.set(100)
        brightness_scale.pack()

    def update_brightness(self, factor):
        original_image = image_io.load_image(self.image_path)
        new_image = np.clip(original_image * factor, 0, 255).astype(np.uint8)
        self.image = new_image
        self.display_image()

    def global_threshold_processing(self):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_loaded'])
            logging.error("没有载入图像,全局阈值处理操作已取消。")
            return
        if len(self.image.shape) != 2:
            tk.messagebox.showerror(language_data[self.current_language]['error'], language_data[self.current_language]['threshold_processing_need_gray'])
            logging.error("全局阈值处理只能用于灰度图。")
            return
        threshold_window = tk.Toplevel(self.master)
        threshold_window.title(language_data[self.current_language]['global_threshold_processing'])
        threshold_scale = tk.Scale(threshold_window, from_=0, to=255, orient=tk.HORIZONTAL,
                                   label=language_data[self.current_language]['threshold_value'],
                                   command=lambda value: self.update_threshold(int(value), threshold_window))
        threshold_scale.set(128)
        threshold_scale.pack()
        apply_button = tk.Button(threshold_window, text=language_data[self.current_language]['apply'],
                                 command=lambda: self.apply_threshold(threshold_scale.get()))
        apply_button.pack()
        self.update_threshold(128, threshold_window)

    def update_threshold(self, threshold, window):
        thresholded_image = np.where(self.image > threshold, 255, 0).astype(np.uint8)
        image = Image.fromarray(thresholded_image)
        canvas_width = 300
        canvas_height = 300
        image_width, image_height = image.size
        scale = min(canvas_width / image_width, canvas_height / image_height)
        if scale < 1:
            new_width = int(image_width * scale)
            new_height = int(image_height * scale)
            image = image.resize((new_width, new_height), Image.LANCZOS)
        else:
            new_width = int(image_width * scale)
            new_height = int(image_height * scale)
            image = image.resize((new_width, new_height), Image.BICUBIC)
        photo = ImageTk.PhotoImage(image)
        if not hasattr(self, 'threshold_canvas'):
            self.threshold_canvas = tk.Canvas(window, width=canvas_width, height=canvas_height)
            self.threshold_canvas.pack()
        else:
            self.threshold_canvas.delete("all")
        x = (canvas_width - new_width) // 2
        y = (canvas_height - new_height) // 2
        self.threshold_canvas.create_image(x, y, anchor=tk.NW, image=photo)
        self.threshold_canvas.image = photo

    def apply_threshold(self, threshold):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_loaded'])
            logging.error("没有载入图像,无法应用全局阈值处理。")
            return
        if len(self.image.shape) != 2:
            tk.messagebox.showerror(language_data[self.current_language]['error'], language_data[self.current_language]['threshold_processing_need_gray'])
            logging.error("全局阈值处理只能用于灰度图。")
            return
        self.image = np.where(self.image > threshold, 255, 0).astype(np.uint8)
        self.display_image()
        logging.info("全局阈值处理已应用到原图。")

    def moving_difference(self):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_loaded'])
            logging.error("没有载入图像,移动差分操作已取消。")
            return
        if len(self.image.shape) != 2:
            tk.messagebox.showerror(language_data[self.current_language]['error'], language_data[self.current_language]['moving_difference_need_gray'])
            logging.error("移动差分功能只能用于灰度图。")
            return
        diff_window = tk.Toplevel(self.master)
        diff_window.title(language_data[self.current_language]['moving_difference'])
        shift_scale = tk.Scale(diff_window, from_=-3, to=3, orient=tk.HORIZONTAL,
                               label=language_data[self.current_language]['shift_pixels'],
                               command=lambda value: self.update_moving_difference(int(value), diff_window))
        shift_scale.set(1)
        shift_scale.pack()
        self.update_moving_difference(1, diff_window)

    def update_moving_difference(self, shift, window):
        if shift == 0:
            diff_image = np.zeros_like(self.image)
        else:
            shifted_image = np.roll(self.image, shift, axis=1)
            diff_image = np.abs(self.image - shifted_image).astype(np.uint8)
        image = Image.fromarray(diff_image)
        canvas_width = 300
        canvas_height = 300
        image_width, image_height = image.size
        scale = min(canvas_width / image_width, canvas_height / image_height)
        if scale < 1:
            new_width = int(image_width * scale)
            new_height = int(image_height * scale)
            image = image.resize((new_width, new_height), Image.LANCZOS)
        else:
            new_width = int(image_width * scale)
            new_height = int(image_height * scale)
            image = image.resize((new_width, new_height), Image.BICUBIC)
        photo = ImageTk.PhotoImage(image)
        if not hasattr(self, 'diff_canvas'):
            self.diff_canvas = tk.Canvas(window, width=canvas_width, height=canvas_height)
            self.diff_canvas.pack()
        else:
            self.diff_canvas.delete("all")
        x = (canvas_width - new_width) // 2
        y = (canvas_height - new_height) // 2
        self.diff_canvas.create_image(x, y, anchor=tk.NW, image=photo)
        self.diff_canvas.image = photo

    def generate_mask(self, color):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_loaded'])
            logging.error("没有载入图像,无法生成掩模。")
            return
        if len(self.image.shape) != 3:
            tk.messagebox.showerror(language_data[self.current_language]['error'], language_data[self.current_language]['generate_mask_need_color'])
            logging.error("生成掩模功能只能用于彩色图。")
            return
        if color == "red":
            mask = self.image[:, :, 0] > 128
        elif color == "green":
            mask = self.image[:, :, 1] > 128
        elif color == "blue":
            mask = self.image[:, :, 2] > 128
        mask = (mask * 255).astype(np.uint8)

        mask_window = tk.Toplevel(self.master)
        mask_window.title(language_data[self.current_language]['save_mask_window'])

        canvas = tk.Canvas(mask_window, width=300, height=300)
        canvas.pack()

        image = Image.fromarray(mask)
        canvas_width = canvas.winfo_width()
        canvas_height = canvas.winfo_height()
        image_width, image_height = image.size
        scale = min(canvas_width / image_width, canvas_height / image_height)
        if scale < 1:
            new_width = int(image_width * scale)
            new_height = int(image_height * scale)
            image = image.resize((new_width, new_height), Image.LANCZOS)
        else:
            new_width = int(image_width * scale)
            new_height = int(image_height * scale)
            image = image.resize((new_width, new_height), Image.BICUBIC)
        photo = ImageTk.PhotoImage(image)
        x = (canvas_width - new_width) // 2
        y = (canvas_height - new_height) // 2
        canvas.create_image(x, y, anchor=tk.NW, image=photo)
        canvas.image = photo

        save_button = tk.Button(mask_window, text=language_data[self.current_language]['save_mask'],
                                command=lambda: self.save_mask(mask))
        save_button.pack()

    def save_mask(self, mask):
        save_path = filedialog.asksaveasfilename(defaultextension=config.DEFAULT_SAVE_FORMAT)
        if not save_path:
            logging.info("没有选择保存路径,保存掩模操作已取消。")
            return
        image_io.save_image(mask, save_path)
        logging.info(f"掩模已成功保存到 {save_path}。")

    def apply_and_mask(self):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_loaded'])
            logging.error("没有载入图像,无法应用掩模。")
            return
        mask_path = filedialog.askopenfilename()
        if not mask_path:
            logging.info("没有选择掩模文件,应用掩模操作已取消。")
            return
        try:
            mask = image_io.load_image(mask_path, as_gray=True)
            
            # 处理RGBA图像的情况
            if len(self.image.shape) == 3 and self.image.shape[2] == 4:
                # 创建4通道掩模，保持Alpha通道不变
                mask_rgba = np.zeros_like(self.image)
                mask_rgba[:, :, :3] = np.stack([mask] * 3, axis=-1)  # 复制到RGB通道
                mask_rgba[:, :, 3] = 255  # Alpha通道保持为255(不透明)
                self.image = np.bitwise_and(self.image, mask_rgba).astype(np.uint8)
            else:
                # 原处理逻辑
                if len(self.image.shape) == 3:
                    mask = np.stack([mask] * 3, axis=-1)
                self.image = np.bitwise_and(self.image, mask).astype(np.uint8)
                
            self.display_image()
            logging.info("与运算掩模已应用到原图。")
        except Exception as e:
            tk.messagebox.showerror(language_data[self.current_language]['error'], str(e))
            logging.error(f"应用与运算掩模时出错: {e}")

    def apply_not_mask(self):
        if self.image is None:
            tk.messagebox.showinfo(language_data[self.current_language]['error'], language_data[self.current_language]['no_image_loaded'])
            logging.error("没有载入图像,无法应用掩模。")
            return
        mask_path = filedialog.askopenfilename()
        if not mask_path:
            logging.info("没有选择掩模文件,应用掩模操作已取消。")
            return
        try:
            mask = image_io.load_image(mask_path, as_gray=True)
            
            # 处理RGBA图像的情况
            if len(self.image.shape) == 3 and self.image.shape[2] == 4:
                # 创建4通道掩模，保持Alpha通道不变
                mask_rgba = np.zeros_like(self.image)
                mask_rgba[:, :, :3] = np.stack([mask] * 3, axis=-1)  # 复制到RGB通道
                mask_rgba[:, :, 3] = 255  # Alpha通道保持为255(不透明)
                self.image = np.bitwise_and(self.image, np.invert(mask_rgba)).astype(np.uint8)
            else:
                # 原处理逻辑
                if len(self.image.shape) == 3:
                    mask = np.stack([mask] * 3, axis=-1)
                self.image = np.bitwise_and(self.image, np.invert(mask)).astype(np.uint8)
                
            self.display_image()
            logging.info("非运算掩模已应用到原图。")
        except Exception as e:
            tk.messagebox.showerror(language_data[self.current_language]['error'], str(e))
            logging.error(f"应用非运算掩模时出错: {e}")


if 'brightness_adjust' not in language_data.get('zh', {}):
    language_data['zh']['brightness_adjust'] = '亮度调节'
    language_data['zh']['brightness_percentage'] = '亮度百分比'
    language_data['zh']['no_image_to_be_adjusted'] = '没有图像可调节亮度'

if 'brightness_adjust' not in language_data.get('en', {}):
    language_data['en']['brightness_adjust'] = 'Brightness Adjustment'
    language_data['en']['brightness_percentage'] = 'Brightness Percentage'
    language_data['en']['no_image_to_be_adjusted'] = 'No image to adjust brightness'

if 'threshold_processing' not in language_data.get('zh', {}):
    language_data['zh']['threshold_processing'] = '阈值处理'
    language_data['zh']['global_threshold_processing'] = '全局阈值处理'
    language_data['zh']['threshold_value'] = '阈值'
    language_data['zh']['apply'] = '应用'
    language_data['zh']['threshold_processing_need_gray'] = '全局阈值处理只能用于灰度图。'

if 'threshold_processing' not in language_data.get('en', {}):
    language_data['en']['threshold_processing'] = 'Threshold Processing'
    language_data['en']['global_threshold_processing'] = 'Global Threshold Processing'
    language_data['en']['threshold_value'] = 'Threshold Value'
    language_data['en']['apply'] = 'Apply'
    language_data['en']['threshold_processing_need_gray'] = 'Global threshold processing can only be used on grayscale images.'

if 'edge' not in language_data.get('zh', {}):
    language_data['zh']['edge'] = '边缘'
    language_data['zh']['moving_difference'] = '移动差分'
    language_data['zh']['shift_pixels'] = '移动像素数'
    language_data['zh']['moving_difference_need_gray'] = '移动差分功能只能用于灰度图。'

if 'edge' not in language_data.get('en', {}):
    language_data['en']['edge'] = 'Edge'
    language_data['en']['moving_difference'] = 'Moving Difference'
    language_data['en']['shift_pixels'] = 'Shift Pixels'
    language_data['en']['moving_difference_need_gray'] = 'Moving difference function can only be used on grayscale images.'

if 'mask' not in language_data.get('zh', {}):
    language_data['zh']['mask'] = '掩模'
    language_data['zh']['generate_red_mask'] = '生成红色掩模'
    language_data['zh']['generate_green_mask'] = '生成绿色掩模'
    language_data['zh']['generate_blue_mask'] = '生成蓝色掩模'
    language_data['zh']['apply_mask'] = '应用掩模'
    language_data['zh']['apply_and_mask'] = '应用与运算掩模'
    language_data['zh']['apply_not_mask'] = '应用非运算掩模'
    language_data['zh']['save_mask'] = '保存掩模'
    language_data['zh']['save_mask_window'] = '保存掩模窗口'
    language_data['zh']['generate_mask_need_color'] = '生成掩模功能只能用于彩色图。'

if 'mask' not in language_data.get('en', {}):
    language_data['en']['mask'] = 'Mask'
    language_data['en']['generate_red_mask'] = 'Generate Red Mask'
    language_data['en']['generate_green_mask'] = 'Generate Green Mask'
    language_data['en']['generate_blue_mask'] = 'Generate Blue Mask'
    language_data['en']['apply_mask'] = 'Apply Mask'
    language_data['en']['apply_and_mask'] = 'Apply AND Mask'
    language_data['en']['apply_not_mask'] = 'Apply NOT Mask'
    language_data['en']['save_mask'] = 'Save Mask'
    language_data['en']['save_mask_window'] = 'Save Mask Window'
    language_data['en']['generate_mask_need_color'] = 'Generate mask function can only be used on color images.'

root = tk.Tk()
app = ImageProcessor(root)
root.mainloop()    